﻿using System;
using Microsoft.Win32;
using System.Globalization;

namespace GetFrameworkVersion
{
    class Program
    {
        static void Main(string[] args)
        {
            GetVersionFromRegistry();
            Get45or451FromRegistry();
            DOTNETVersionInfo vers = GetLatestDOTNETVersion();
            Console.WriteLine(vers.FrameworkVersion + "\n" + vers.ServicePack);
            Console.ReadLine();
        }

        private static void GetVersionFromRegistry()
        {

            using (RegistryKey ndpKey = RegistryKey.OpenSubKey(@"SOFTWARE\Microsoft\NET Framework Setup\NDP\"))
            {
                foreach (string versionKeyName in ndpKey.GetSubKeyNames())
                {
                    if (versionKeyName.StartsWith("v"))
                    {

                        RegistryKey versionKey = ndpKey.OpenSubKey(versionKeyName);
                        string name = (string)versionKey.GetValue("Version", "");
                        string sp = versionKey.GetValue("SP", "").ToString();
                        string install = versionKey.GetValue("Install", "").ToString();
                        if (install == "") //no install info, must be later.
                            Console.WriteLine(versionKeyName + "  " + name);
                        else
                        {
                            if (sp != "" && install == "1")
                            {
                                Console.WriteLine(versionKeyName + "  " + name + "  SP" + sp);
                            }

                        }
                        if (name != "")
                        {
                            continue;
                        }
                        foreach (string subKeyName in versionKey.GetSubKeyNames())
                        {
                            RegistryKey subKey = versionKey.OpenSubKey(subKeyName);
                            name = (string)subKey.GetValue("Version", "");
                            if (name != "")
                                sp = subKey.GetValue("SP", "").ToString();
                            install = subKey.GetValue("Install", "").ToString();
                            if (install == "") //no install info, must be later.
                                Console.WriteLine(versionKeyName + "  " + name);
                            else
                            {
                                if (sp != "" && install == "1")
                                {
                                    Console.WriteLine("  " + subKeyName + "  " + name + "  SP" + sp);
                                }
                                else if (install == "1")
                                {
                                    Console.WriteLine("  " + subKeyName + "  " + name);
                                }

                            }

                        }

                    }
                }
            }

        }

        private static void Get45or451FromRegistry()
        {
            using (RegistryKey ndpKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine,
               RegistryView.Registry32).OpenSubKey(@"SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full\"))
            {
                int releaseKey = (int)ndpKey.GetValue("Release");
                {
                    if (releaseKey == 378389)

                        Console.WriteLine("The .NET Framework version 4.5 is installed");

                    if (releaseKey == 378758)

                        Console.WriteLine("The .NET Framework version 4.5.1  is installed");

                }
            }
        }

        public struct DOTNETVersionInfo
        {
            public double FrameworkVersion;
            public int ServicePack;
        }

        public static bool CheckRequiredDOTNETVersion(DOTNETVersionInfo required)
        {
            bool reslt = false;
            double tmpFramework = 0;
            int tmpSP = 0;
            try
            {
                RegistryKey installed_versions = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\NET Framework Setup\NDP", false);
                string[] version_names = installed_versions.GetSubKeyNames();
                string tmpBaseVersion;
                //check each installed version
                foreach (string ver in version_names)
                {
                    //set default values
                    tmpFramework = 0;
                    tmpSP = 0;
                    tmpBaseVersion = string.Empty;
                    try
                    {
                        //version names start with 'v', eg, 'v3.5' which needs to be trimmed off before conversion
                        string tmpFullVersion = ver.Remove(0, 1);
                        //now remove the minor versions 2.0.5725
                        if (tmpFullVersion.Length > 3)
                        {
                            tmpBaseVersion = tmpFullVersion.Remove(tmpFullVersion.IndexOfAny((".").ToCharArray(), 2), tmpFullVersion.Length - 3);
                        }
                        else //its just 3 digit version
                        {
                            tmpBaseVersion = tmpFullVersion;
                        }
                        double basicVersion = 0;
                        if (double.TryParse(tmpBaseVersion, out basicVersion))
                        {
                            tmpFramework = basicVersion;
                        }
                    }
                    catch
                    {
                        tmpFramework = 0;
                    }
                    //The service pack key might not exist so it might throw an error
                    try
                    {
                        tmpSP = Convert.ToInt32(installed_versions.OpenSubKey(ver).GetValue("SP", 0));
                    }
                    catch { }
                    if (tmpFramework == required.FrameworkVersion && tmpSP == required.ServicePack)
                    {
                        reslt = true;
                        break;
                    }
                }
            }
            catch (Exception exp)
            {
                string message = "Error occured:" + exp.Message;
                if (exp is System.Security.SecurityException)
                {
                    message += "\n Unable to find .NET Framework version. \n The user does not have the permissions required to access the registry key:\n"
                            + @"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP";
                }
                Console.WriteLine(message);
            }
            return reslt;
        }

        public static DOTNETVersionInfo GetLatestDOTNETVersion()
        {
            DOTNETVersionInfo dnVer;
            dnVer.FrameworkVersion = 0;
            dnVer.ServicePack = 0;
            try
            {
                RegistryKey installed_versions = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\NET Framework Setup\NDP", false);
                string[] version_names = installed_versions.GetSubKeyNames();
                //version names start with 'v', eg, 'v3.5' which needs to be trimmed off before conversion
                double Framework = Convert.ToDouble(version_names[version_names.Length - 1].Remove(0, 1), CultureInfo.InvariantCulture);
                dnVer.FrameworkVersion = Framework;
                //The service pack key might not exist so it might throw an error
                int SP = 0;
                try
                {
                    SP = Convert.ToInt32(installed_versions.OpenSubKey(version_names[version_names.Length - 1]).GetValue("SP", 0));
                }
                catch { }
                dnVer.ServicePack = SP;
            }
            catch (Exception exp)
            {
                string message = "Error occured:" + exp.Message;
                if (exp is System.Security.SecurityException)
                {
                    message += "\n Unable to find .NET Framework version. \n The user does not have the permissions required to access the registry key:\n"
                            + @"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP";
                }
                Console.WriteLine(message);
            }
            return dnVer;
        }
    }


}
